package com.jia.train.seat.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.pinyin.PinyinUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jia.train.global.enums.BusinessEnum;
import com.jia.train.global.exception.BusinessException;
import com.jia.train.global.page.PageResponse;
import com.jia.train.global.utils.SnowIdUtil;
import com.jia.train.seat.entity.DailyTrips;
import com.jia.train.seat.entity.DailyTripsExample;
import com.jia.train.seat.entity.Trips;
import com.jia.train.seat.entity.TripsExample;
import com.jia.train.seat.mapper.DailyTripsMapper;
import com.jia.train.seat.mapper.TripsMapper;
import com.jia.train.seat.request.DailyTripsQueryRequest;
import com.jia.train.seat.request.DailyTripsSaveRequest;
import com.jia.train.seat.response.DailyTripsQueryResponse;
import com.jia.train.seat.response.DailyTripsSaveResponse;
import com.jia.train.seat.service.*;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class DailyTripsServiceImpl implements DailyTripsService {

    public static final Logger logger = LoggerFactory.getLogger(DailyTripsServiceImpl.class);

    @Resource
    private DailyTripsMapper dailyTripsMapper;

    @Resource
    private TripsMapper tripsMapper;

    @Resource
    private DailyTripStationService dailyTripStationService;

    @Resource
    private DailyTrainCarriageService dailyTrainCarriageService;

    @Resource
    private DailyTrainSeatService dailyTrainSeatService;

    @Resource
    private DailyTrainTicketService dailyTrainTicketService;

    @Resource
    private TransactionTemplate transactionTemplate;

    @Override
    public DailyTripsSaveResponse insert(DailyTripsSaveRequest request) {
        DailyTrips dailyTrips = BeanUtil.copyProperties(request, DailyTrips.class);
        DateTime now = DateTime.now();
        String start = request.getStart();
        String end = request.getEnd();
        String code = request.getCode();
        if (ObjectUtil.isNotEmpty(start)) {
            dailyTrips.setStartPinyin(PinyinUtil.getPinyin(start, ""));
        }
        if (ObjectUtil.isNotEmpty(end)) {
            dailyTrips.setEndPinyin(PinyinUtil.getPinyin(end, ""));
        }
        if (ObjectUtil.isEmpty(dailyTrips.getId())) {
            if (getDailyTripsCount(code) > 0) {
                throw new BusinessException(BusinessEnum.TRAIN_NUMBER_ALREADY_EXISTS);
            }
            dailyTrips.setId(SnowIdUtil.getLongSnowNextId());
            dailyTrips.setCreateTime(now);
            dailyTripsMapper.insert(dailyTrips);
        } else {
            dailyTrips.setUpdateTime(now);
            dailyTripsMapper.updateByPrimaryKeySelective(dailyTrips);
        }

        return BeanUtil.copyProperties(dailyTrips, DailyTripsSaveResponse.class);
    }

    @Override
    public PageResponse<DailyTripsQueryResponse> selectPage(DailyTripsQueryRequest request) {

        String tripCode = request.getTripCode();
        Date date = request.getDate();

        DailyTripsExample dailyTripsExample = new DailyTripsExample();
        // 构造查询条件
        DailyTripsExample.Criteria criteria = dailyTripsExample.createCriteria();
        if (StringUtils.hasText(tripCode)) {
            criteria.andCodeEqualTo(tripCode);
        }
        if (ObjectUtil.isNotNull(date)) {
            criteria.andDateEqualTo(date);
        }

        // 构造分页
        PageHelper.startPage(request.getPage(), request.getSize());
        List<DailyTrips> DailyTripsList = dailyTripsMapper.selectByExample(dailyTripsExample);
        PageInfo<DailyTrips> pageInfo = new PageInfo<>(DailyTripsList);

        List<DailyTripsQueryResponse> list
                = BeanUtil.copyToList(DailyTripsList, DailyTripsQueryResponse.class);

        PageResponse<DailyTripsQueryResponse> pageResponse = new PageResponse<>();
        pageResponse.setTotal(pageInfo.getTotal());
        pageResponse.setList(list);
        return pageResponse;
    }

    @Override
    public List<DailyTripsQueryResponse> selectList() {
        DailyTripsExample DailyTripsExample = new DailyTripsExample();
        DailyTripsExample.setOrderByClause("date desc,code asc");
        List<DailyTrips> DailyTripsList = dailyTripsMapper.selectByExample(DailyTripsExample);
        return BeanUtil.copyToList(DailyTripsList, DailyTripsQueryResponse.class);
    }

    @Override
    public void deleteDailyTrips(Long id) {
        dailyTripsMapper.deleteByPrimaryKey(id);
    }

    @Override
    public void genDailyTrip(Date date) {
        logger.info("生成日期：{} 的车次信息", DateUtil.formatDate(date));

        TripsExample tripsExample = new TripsExample();
        List<Trips> tripsList = tripsMapper.selectByExample(tripsExample);
        if (CollectionUtils.isEmpty(tripsList)) {
            logger.info("没有车次基础数据：{},任务结束", tripsList);
            return;
        }

        List<DailyTrips> dailyTripsList = new ArrayList<>();
        DailyTrips dailyTrips;
        for (Trips trips : tripsList) {
            dailyTrips = BeanUtil.copyProperties(trips, DailyTrips.class);
            dailyTrips.setId(SnowIdUtil.getLongSnowNextId());
            dailyTrips.setCreateTime(new DateTime());
            dailyTrips.setDate(date);
            dailyTripsList.add(dailyTrips);
        }

        DailyTripsExample dailyTripsExample = new DailyTripsExample();
        DailyTripsExample.Criteria criteria = dailyTripsExample.createCriteria();
        criteria.andDateEqualTo(date);

        transactionTemplate.executeWithoutResult(status -> {
            try {
                // 生成 每日车次
                dailyTripsMapper.deleteByExample(dailyTripsExample);
                dailyTripsMapper.batchInsert(dailyTripsList);
                for (DailyTrips trips : dailyTripsList) {
                    String code = trips.getCode();
                    // 生成 每日车次车站
                    dailyTripStationService.genDailyTripStation(date, code);
                    // 生成 每日车厢
                    dailyTrainCarriageService.genDailyTrainCarriage(date, code);
                    // 生成 每日座位
                    dailyTrainSeatService.genDailyTrainSeat(date, code);
                    // 初始化 余票
                    dailyTrainTicketService.genDailyTrainTicket(date, code);
                }
            } catch (Exception e) {
                status.setRollbackOnly();
                throw new RuntimeException("业务执行失败: " + e); // 重新抛出异常（关键）
            }
        });


    }

    private long getDailyTripsCount(String code) {
        DailyTripsExample DailyTripsExample = new DailyTripsExample();
        DailyTripsExample.Criteria criteria = DailyTripsExample.createCriteria();
        criteria.andCodeEqualTo(code);
        return dailyTripsMapper.countByExample(DailyTripsExample);
    }
}
